package utils;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;


public class PostConn {  
	    URL url;    
	    HttpURLConnection conn;    
	    String boundary = "--------imagepost";    
	    Map<String, String> textParams = new HashMap<String, String>();    
	    Map<String, File> fileparams = new HashMap<String, File>();    
	    DataOutputStream ds;    
	    
	    public PostConn(String url) throws MalformedURLException {    
	        this.url = new URL(url);    
	    }    
	    //重新设置要请求的服务器地址，即上传文件的地址。    
	    public void setUrl(String url) throws Exception {    
	        this.url = new URL(url);    
	    }    
	    //增加一个普通字符串数据到form表单数据中    
	    public void addTextParameter(String name, String value) {    
	        textParams.put(name, value);    
	    }    
	    //增加一个文件到form表单数据中    
	    public void addFileParameter(String name, File value) {    
	        fileparams.put(name, value);    
	    }    
	    // 清空所有已添加的form表单数据    
	    public void clearAllParameters() {    
	        textParams.clear();    
	        fileparams.clear();    
	    }    
	    // 发送数据到服务器，返回一个字节包含服务器的返回结果的数组    
		public byte[] send() throws Exception {    
	        try {
				initConnection();
			} catch (IOException e1) {
				throw new Exception("IOException in initConnection,"+e1.getMessage());
			}    
	        try {    
	            conn.connect();    
	        } catch (SocketTimeoutException e) {    
	        	throw new Exception("SocketTimeoutException in conn.connect,"+e.getMessage());
	        } catch (IOException e) {
	        	throw new Exception("IOException in conn.connect,"+e.getMessage());
			}    
	        try {
				ds = new DataOutputStream(conn.getOutputStream());
			} catch (IOException e1) {
				throw new Exception("IOException in DataOutputStream,"+e1.getMessage());
			}    
	        try {
				writeFileParams();
			} catch (IOException e1) {
				throw new Exception("IOException in writeFileParams,"+e1.getMessage());
			}    
	        try {
				writeStringParams();
			} catch (IOException e1) {
				throw new Exception("IOException in writeStringParams,"+e1.getMessage());
			}    
	        try {
				paramsEnd();
			} catch (IOException e1) {
				throw new Exception("IOException in paramsEnd,"+e1.getMessage());
			}    
	        InputStream in = null;
			try {
				in = conn.getInputStream();
			} catch (IOException e1) {
				throw new Exception("IOException in getInputStream,"+e1.getMessage());
			}    
	        ByteArrayOutputStream out = new ByteArrayOutputStream();    
	        int b;
	        try {
				while ((b = in.read()) != -1) {    
				    out.write(b);
				}
			} catch (IOException e2) {
				throw new Exception("IOException in while,"+e2.getMessage());
			}    
	        try {
				out.flush();
			} catch (IOException e1) {
				throw new Exception("IOException in out.flush(),"+e1.getMessage());
			}    
	        
	        byte[] re  = null;  
	        try {  
	            re = out.toByteArray();  
	        } catch (Exception e) {  
	            e.printStackTrace();  
	               out=null;  
	               conn= null;  
	        }finally{  
	                try {
						out.close();
					} catch (IOException e) {
					}  
	                out=null;  
	                conn.disconnect();    
	                conn= null;  
	        }  
	        
	        return re;    
	    }    
	    //文件上传的connection的一些必须设置    
	    private void initConnection() throws IOException {    
	        conn = (HttpURLConnection) this.url.openConnection();    
	        conn.setDoOutput(true);    
	        conn.setUseCaches(false);    
	        conn.setConnectTimeout(10000); //连接超时为10秒    
	        conn.setRequestMethod("POST");    
	        conn.setRequestProperty("Content-Type",    
	                "multipart/form-data; boundary=" + boundary);    
	        conn.setChunkedStreamingMode(1024 * 50);    
	    }    
	    //普通字符串数据    
	    private void writeStringParams() throws IOException {    
	        Set<String> keySet = textParams.keySet();    
	        for (Iterator<String> it = keySet.iterator(); it.hasNext();) {    
	            String name = it.next();    
	            String value = textParams.get(name);    
	            ds.writeBytes("--" + boundary + "\r\n");    
	            ds.writeBytes("Content-Disposition: form-data; name=\"" + name    
	                    + "\"\r\n");    
	            ds.writeBytes("\r\n");    
	            ds.writeBytes(encode(value) + "\r\n");    
	        }    
	    }    
	    //文件数据    
	    private void writeFileParams() throws IOException {    
	        Set<String> keySet = fileparams.keySet();    
	        for (Iterator<String> it = keySet.iterator(); it.hasNext();) {    
	            String name = it.next();    
	            File value = fileparams.get(name);    
	            ds.writeBytes("--" + boundary + "\r\n");    
	            ds.writeBytes("Content-Disposition: form-data; name=\"" + name    
	                    + "\"; filename=\"" + encode(value.getName()) + "\"\r\n");    
	            ds.writeBytes("Content-Type: " + getContentType(value) + "\r\n");    
	            ds.writeBytes("\r\n");    
	            ds.write(getBytes(value));    
	            ds.writeBytes("\r\n");    
	        }    
	    }    
	    //获取文件的上传类型，图片格式为image/png,image/jpg等。非图片为application/octet-stream    
	    private String getContentType(File f) {    
	            
	    	return "image/png";
	      //return "application/octet-stream";  // 此行不再细分是否为图片，全部作为application/octet-stream 类型    
//	        ImageInputStream imagein = ImageIO.createImageInputStream(f);    
//	        if (imagein == null) {    
//	            return "application/octet-stream";    
//	        }    
//	        Iterator<ImageReader> it = ImageIO.getImageReaders(imagein);    
//	        if (!it.hasNext()) {    
//	            imagein.close();    
//	            return "application/octet-stream";    
//	        }    
//	        imagein.close();    
//	        return "image/" + it.next().getFormatName().toLowerCase();//将FormatName返回的值转换成小写，默认为大写    
	    
	    }    
	    //把文件转换成字节数组    
	    private byte[] getBytes(File f) throws IOException  {    
	        FileInputStream in = new FileInputStream(f);    
	        ByteArrayOutputStream out = new ByteArrayOutputStream();    
	        byte[] b = new byte[1024];    
	        int n;    
	        while ((n = in.read(b)) != -1) {    
	            out.write(b, 0, n);    
	        }    
	        in.close();    
	        return out.toByteArray();    
	    }    
	    //添加结尾数据    
	    private void paramsEnd() throws IOException {    
	        ds.writeBytes("--" + boundary + "--" + "\r\n");    
	        ds.writeBytes("\r\n");    
	    }    
	    // 对包含中文的字符串进行转码，此为UTF-8。服务器那边要进行一次解码    
	    private String encode(String value) throws UnsupportedEncodingException {    
	        return URLEncoder.encode(value, "UTF-8");
	    }    
}
